#include<iostream>
#include<deque>
#include<cstring>
#include <climits>
#include<queue>
using namespace std;
const int N=1e3+10;
typedef pair<int,int> PII;
char numset[N][N];
int dist[4][N][N];
int n,m;

int dx[4]={1,-1,0,0};
int dy[4]={0,0,-1,1};

typedef struct node
{
    int Weight;
    int x,y;
    bool operator <(const node& a) const
    {
        return Weight>a.Weight;
    }
}node;

void bfs(int Serialn)
{
    char flag=Serialn+'0';
    priority_queue<node> pq;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            dist[Serialn][i][j]=-1;
            if(numset[i][j]==flag)
            {
                pq.push({0,i,j});
                dist[Serialn][i][j]=0;
            }
        }
    }

    while(!pq.empty())
    {
        int topnum=pq.top().Weight;
        int x=pq.top().x;
        int y=pq.top().y;

        pq.pop();

        if(topnum>dist[Serialn][x][y])
        {
            continue;
        }

        for(int i=0;i<4;i++)
        {
            int newx=x+dx[i];
            int newy=y+dy[i];

            if(newx<=n&&newy<=m&&newy>=1&&newx>=1
                &&numset[newx][newy]!='#')
            {
                int w=(numset[newx][newy]=='.'?1:0);
                if(dist[Serialn][newx][newy]==-1||topnum+w<dist[Serialn][newx][newy])
                {  
                    dist[Serialn][newx][newy]=topnum+w;
                    if(numset[newx][newy]=='.')
                    {
                        pq.push({dist[Serialn][newx][newy],newx,newy});
                    }
                    
                }
            }
        }
    }
}

int main()
{
    cin>>n>>m;

    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cin>>numset[i][j];
        }
    }

    bfs(1);
    bfs(2);
    bfs(3);

    int ret=INT_MAX;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(dist[1][i][j]==-1||dist[2][i][j]==-1||dist[3][i][j]==-1) continue;
            if(numset[i][j]=='.')
            {
                ret=min(ret,dist[1][i][j]+dist[2][i][j]+dist[3][i][j]-2);
            }
            else 
            {
                ret=min(ret,dist[1][i][j]+dist[2][i][j]+dist[3][i][j]);
            }
        }
    }
    if(ret == INT_MAX) cout << -1 << "\n";
    else cout << ret << "\n";
}